using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using UselessExplorer.Controller;
using UselessExplorer.Properties;
using UselessExplorer.UI;

namespace UselessExplorer
{
    public partial class MainWindow : Form
    {
        ClsGlobal global = ClsGlobal.Instance;
        FileExplorerController explorer = null;
        DirectoryTree dirTree = null;
        
        private string DefaultDriveName = @"C:\";
        private int childFormNumber = 0;

        private static MainWindow instance;
        public static MainWindow Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new MainWindow();
                }
                return instance;
            }
        }

        public MainWindow ()
        {
            InitializeComponent();
            
            explorer = new FileExplorerController();
            InitLoad();
        }

        #region PreDefinedCode
        private void ShowNewForm ( object sender, EventArgs e )
        {
            // Create a new instance of the child form.
            Form childForm = new Form();
            // Make it a child of this MDI form before showing it.
            childForm.MdiParent = this;
            childForm.Text = "Window " + childFormNumber++;
            childForm.Show();
        }



        private void OpenFile ( object sender, EventArgs e )
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.Personal );
            openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
            if (openFileDialog.ShowDialog( this ) == DialogResult.OK)
            {
                string FileName = openFileDialog.FileName;
                // TODO: Add code here to open the file.
            }
        }

        private void SaveAsToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.Personal );
            saveFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
            if (saveFileDialog.ShowDialog( this ) == DialogResult.OK)
            {
                string FileName = saveFileDialog.FileName;
                // TODO: Add code here to save the current contents of the form to a file.
            }
        }

        private void ExitToolsStripMenuItem_Click ( object sender, EventArgs e )
        {
            Application.Exit();
        }

        private void CutToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            // TODO: Use System.Windows.Forms.Clipboard to insert the selected text or images into the clipboard
        }

        private void CopyToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            // TODO: Use System.Windows.Forms.Clipboard to insert the selected text or images into the clipboard
        }

        private void PasteToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            // TODO: Use System.Windows.Forms.Clipboard.GetText() or System.Windows.Forms.GetData to retrieve information from the clipboard.
        }

        private void ToolBarToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            toolStrip.Visible = toolBarToolStripMenuItem.Checked;
        }

        private void StatusBarToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            statusStrip.Visible = statusBarToolStripMenuItem.Checked;
        }

        private void CascadeToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            LayoutMdi( MdiLayout.Cascade );
        }

        private void TileVerticleToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            LayoutMdi( MdiLayout.TileVertical );
        }

        private void TileHorizontalToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            LayoutMdi( MdiLayout.TileHorizontal );
        }

        private void ArrangeIconsToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            LayoutMdi( MdiLayout.ArrangeIcons );
        }

        private void CloseAllToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            foreach (Form childForm in MdiChildren)
            {
                childForm.Close();
            }
        }

        private void toolStripSearchReplace_Click ( object sender, EventArgs e )
        {
            frmSearchReplace srchReplace = new frmSearchReplace();
            srchReplace.ShowDialog();
        }

        private void dirTree_NodeMouseClick ( object sender, TreeNodeMouseClickEventArgs e )
        {
            dirTree.SelectedNode = e.Node;
            dirTree.SelectedNode.ImageIndex = 1;
        }

        private void toolStripComboBox1_SelectedIndexChanged ( object sender, EventArgs e )
        {
            InitLoad();
        }

        private void errorLogsToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            frmTraces trace = new frmTraces();
            if (!trace.IsDisposed)
            {
                global.InitialiseTrace( trace );
                trace.Show();
            }
        }

        private void lvFiles_MouseDown ( object sender, MouseEventArgs e )
        {
            if (MouseButtons == MouseButtons.Right && lvFiles.SelectedItems.Count == 0)
                lvFiles.ContextMenuStrip = contextMenuListboxAll;
        }

        private void deleteFolderToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            MessageBox.Show( "Will be implemented soon" );
        }

        private void propertiesToolStripMenuItem2_Click ( object sender, EventArgs e )
        {
            MessageBox.Show( "Will be implemented soon" );
        }

        private void tabFtpClient_Click ( object sender, EventArgs e )
        {

        }

        void dirTree_BeforeSelect ( object sender, TreeViewCancelEventArgs e )
        {
            e.Node.StateImageIndex = 0;
        }

        private void dirTree_AfterSelect ( object sender, TreeViewEventArgs e )
        {
            LoadFiles( dirTree.SelectedNode.FullPath, false );
            dirTree.SelectedNode = e.Node;
            dirTree.SelectedNode.ImageIndex = 0;
        }

        private void addExtension_Click ( object sender, EventArgs e )
        {
            string filepath = String.Format( @"{0}{1}", dirTree.SelectedNode.FullPath, lvFiles.SelectedItems[0].Text.ToString() );

            ClsGlobal.StatusExtnAdd status = explorer.AddExtension( filepath );

            if (status == ClsGlobal.StatusExtnAdd.ExtensionAdded)
            {
                tsStatusLabel.Text = UselessResources.ExpAddExtnSuccess;
            }
            else if (status == ClsGlobal.StatusExtnAdd.Failed)
            {
                tsStatusLabel.Text = UselessResources.ExpAddExtnFailed;
            }
            else if (status == ClsGlobal.StatusExtnAdd.Restricted)
            {
                tsStatusLabel.Text = UselessResources.ExpAddExtnFailed;
            }
        }

        private void deleteToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            if (MessageBox.Show( UselessExplorer.Properties.UselessResources.ExpDelFolderWarning, "Info", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1 ) == DialogResult.Yes)
            {
                // Delets the Folder
                explorer.DeleteFolderOrFile( dirTree.SelectedNode.FullPath.ToString() );

                // Loads the directory tree again
                InitLoad();

                dirTree.Nodes[0].Expand();
                lvFiles.Items.Clear();
            }
        }

        private void lvFiles_DoubleClick ( object sender, EventArgs e )
        {
            if (lvFiles.SelectedItems[0].Tag.GetType() == typeof( DirectoryInfo ))
            {
                string path = dirTree.SelectedNode.FullPath + @"\" + lvFiles.SelectedItems[0].Text;

                for (int Index = 0; Index < dirTree.SelectedNode.Nodes.Count; Index++)
                {
                    string val = dirTree.SelectedNode.Nodes[Index].Text;
                    if (dirTree.SelectedNode.Nodes[Index].Text.Equals( lvFiles.SelectedItems[0].Text ))
                    {
                        dirTree.SelectedNode = dirTree.SelectedNode.Nodes[Index];
                        dirTree.SelectedNode.Expand();
                        break;
                    }
                }
            }
        }

        private void deleteContextMenu_Click ( object sender, EventArgs e )
        {
            string fileName = lvFiles.SelectedItems[0].Text.ToString();
            string fullPath = dirTree.SelectedNode.FullPath + @"\" + fileName;

            explorer.DeleteFolderOrFile( fullPath );

            if (!explorer.IsDirectory( fullPath ))
            {
                bool isRootNode = false;
                if (dirTree.SelectedNode.Text == cbDriveList.SelectedItem.ToString())
                    isRootNode = true;
                LoadFiles( dirTree.SelectedNode.FullPath.ToString(), isRootNode );
            }
            else
            {
                LoadFiles( dirTree.SelectedNode.FullPath, false );
            }

            dirTree.RefreshDisplay();
        }

        private void propertiesContextMenu_Click ( object sender, EventArgs e )
        {
            string filePath;
            if (lvFiles.SelectedItems[0] == null)
            {
                filePath = dirTree.SelectedNode.FullPath;
                frmProperties fp = new frmProperties( filePath, true );
                fp.ShowDialog();
            }
            else
            {
                filePath = dirTree.SelectedNode.FullPath + @"\" + lvFiles.SelectedItems[0].Text;
                if (!explorer.IsDirectory( filePath ))
                {
                    frmProperties fp = new frmProperties( filePath, false );
                    fp.ShowDialog();
                }
                else
                {
                    frmProperties fp = new frmProperties( filePath, explorer.IsDirectory( filePath ) );
                    fp.StartPosition = FormStartPosition.CenterParent;
                    fp.ShowDialog();
                }
            }
        }

        private void tmrClean_Tick ( object sender, EventArgs e )
        {
            tmrClean.Stop();
            tmrClean.Enabled = false;
            tsStatusLabel.Text = String.Empty;
        }

        private void fileToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            frmPromptBox fpb = frmPromptBox.Instance;
            fpb.IsFolder = false;
            fpb.ShowDialog();

            if (fpb.FileName != null)
            {
                string file = fpb.FileName;
                string dirPath = dirTree.SelectedNode.FullPath;
                FileInfo fInfo = new FileInfo( dirPath + @"\" + file );
                FileStream fstr = fInfo.Create();
                fstr.Close();

                bool isRootNode = false;

                isRootNode = (dirTree.SelectedNode.Text == cbDriveList.SelectedItem.ToString()) ? true : false;
                LoadFiles( dirTree.SelectedNode.FullPath.ToString(), isRootNode );
            }
        }

        private void propertiesToolStripMenuItem1_Click ( object sender, EventArgs e )
        {
            frmProperties fp = new frmProperties( dirTree.SelectedNode.FullPath, true );
            fp.ShowDialog();
        }

        private void folderToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            frmPromptBox fpb = frmPromptBox.Instance;
            fpb.IsFolder = true;
            fpb.ShowDialog();

            if (fpb.FileName != null)
            {
                string folderName = fpb.FileName;
                string dirPath = dirTree.SelectedNode.FullPath;
                Directory.CreateDirectory( dirPath + @"\" + folderName );

                dirTree.Refresh();
                dirTree.SelectedNode.Expand();
            }

        }

        private void allowedExtensionsToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            OpenPrefrencesTab();
        }

        private void OpenPrefrencesTab ()
        {
            tabCtrl.SelectedTab = tabPrefrences;
        }

        private void MainWindow_KeyDown ( object sender, KeyEventArgs e )
        {
            if (e.Control && e.KeyCode.ToString() == "K")
            {
                OpenPrefrencesTab();
            }
        }

        private void searchAndReplaceMultipleFilesToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            frmSearchReplace fsr = new frmSearchReplace();
            fsr.Show();
        }

        private void createFolderToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            MessageBox.Show( "Will be implemented soon" );
        }

        private void toolStripDocumentation_Click ( object sender, EventArgs e )
        {
            frmVB6Documenter doc = new frmVB6Documenter();
            doc.Show();
        }

        private void networkMonitoringToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            tabCtrl.SelectedTab = tabNetworkStatus;
        }

        private void vB6DocumentorToolStripMenuItem_Click ( object sender, EventArgs e )
        {
            frmVB6Documenter vb6doc = new frmVB6Documenter();
            vb6doc.Show();
        }

        private void tsNetworkMonitor_Click ( object sender, EventArgs e )
        {
            tabCtrl.SelectedTab = tabNetworkStatus;
        }

        private void lvFiles_SelectedIndexChanged ( object sender, EventArgs e )
        {
            OpenFileToView( MouseButtons );
        }
        #endregion

        private void MainWindow_Load ( object sender, EventArgs e )
        {
            this.MainWindowContainer.Dock = DockStyle.Fill;
            SetWindowText();
#if !DEBUG
            
            // Splash Screen
            this.Hide();
            frmSplash fs = new frmSplash();
            fs.ShowDialog();
            this.Show();
#endif
            // Intitalisation of Configuration
            global.initialiseTrace();
            global.Extensions = ucPrefrencesExtension.readConfiguration();



            var Drives = from i in Directory.GetLogicalDrives()
                         select i;

            foreach (string drive in Drives)
            {
                cbDriveList.Items.Add( drive );
            }

            //cbDriveList.SelectedItem = cbDriveList.Items[0];
        }

        private void InitLoad ()
        {
            lvFiles.Items.Clear();

            string DriveName = String.Empty;

            if (cbDriveList.SelectedItem != null)
            {
                DriveName = cbDriveList.SelectedItem.ToString();
            }
            else
            {
                DriveName = DefaultDriveName;
            }

            dirTree = explorer.InitLoad( DriveName );

            // Adding the Directory Tree Control to the UI
            this.MainWindowContainer.Panel1.Controls.Add( dirTree );
            dirTree.Dock = DockStyle.Fill;

            // Adding Event Handlers to the Directory Tree Control
            dirTree.NodeMouseClick += new TreeNodeMouseClickEventHandler( dirTree_NodeMouseClick );
            dirTree.AfterSelect += new TreeViewEventHandler( dirTree_AfterSelect );
            dirTree.BeforeSelect += new TreeViewCancelEventHandler( dirTree_BeforeSelect );

            // Adding the ContextMenu to the Directory Tree
            dirTree.ContextMenuStrip = contextMenuTreeView;

            // Adding the Images to the DirectoryTree Control
            dirTree.ImageList = folderImageList;

        }

        /// <summary>
        /// Set Some of the default texts of the Window
        /// </summary>
        private void SetWindowText ()
        {
            this.lblVersion.Text = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
            this.tsLblPathView.Text = String.Empty;
            this.Text = UselessExplorer.Properties.UselessResources.frmExplorerWinTitle;
        }

        private void OpenFileToView ( MouseButtons mb )
        {
            bool flag = true;
            try
            {
                if (mb == MouseButtons.Left)
                {
                    if (lvFiles.SelectedItems != null && lvFiles.SelectedItems.Count > 0) //&& !fileList.SelectedItem.ToString().Equals(UselessResources.ExpFilesNotFound))
                    {
                        string initialPath = dirTree.SelectedNode.FullPath;
                        string filepath = initialPath + @"\" + lvFiles.SelectedItems[0].Text.ToString();

                        if (!explorer.IsDirectory( filepath ))
                        {
                            for (int i = 0; i < contextMenuListboxItem.Items.Count; i++)
                            {
                                if (contextMenuListboxItem.Items[i].Text.Equals( "Add Extension" ))
                                {
                                    contextMenuListboxItem.Items.RemoveAt( i );
                                }
                            }

                            lvFiles.ContextMenuStrip = contextMenuListboxItem;
                            tsLblPathView.Text = filepath;
                            DirectoryInfo dirInfo = new DirectoryInfo( filepath );

                            foreach (string extension in global.Extensions)
                            {
                                flag = (dirInfo.Extension.ToUpper() != extension.ToUpper()) ? true : false;
                                if (!flag)
                                    break;
                            }

                            if (!flag)
                            {
                                frmTxtViewer txtView = new frmTxtViewer( filepath );
                                txtView.ShowDialog();
                            }
                            else
                            {
                                contextMenuListboxItem.Items.Add( "Add Extension", null, new EventHandler( addExtension_Click ) );
                                tsStatusLabel.Text = UselessResources.ExpFileViewFailed;
                                tsStatusLabel.ForeColor = Color.Red;
                                tmrClean.Enabled = true;
                                tmrClean.Start();
                            }
                        }
                    }
                    else
                    {
                        lvFiles.ContextMenuStrip = contextMenuListboxItem;
                    }

                }
                else if (mb == MouseButtons.Right && lvFiles.SelectedItems.Count > 0)
                {
                    lvFiles.ContextMenuStrip = contextMenuListboxItem;
                }
                else
                {
                    lvFiles.ContextMenuStrip = contextMenuListboxAll;
                }
            }
            catch (Exception ex)
            {
                global.WriteLogs( Logger.LogsCategory.Exception, ex );
            }
        }
      
        private void bgWorkerLoadData_DoWork ( object sender, DoWorkEventArgs e )
        {
            bgWorkerLoadData.ReportProgress( 10 );

            try
            {

                bgWorkerLoadData.ReportProgress( 30 );

                string[] arg = e.Argument.ToString().Split( '~' );

                bgWorkerLoadData.ReportProgress( 50 );

                explorer.LoadData( arg[0], Convert.ToBoolean( arg[1] ) );

                bgWorkerLoadData.ReportProgress( 80 );

                bgWorkerLoadData.ReportProgress( 100 );
            }
            catch (Exception ex)
            {
                e.Result = ex;   
            }
        }

        private void bgWorkerLoadData_ProgressChanged ( object sender, ProgressChangedEventArgs e )
        {
            ProgressBar.Value = e.ProgressPercentage;
        }

        private void bgWorkerLoadData_RunWorkerCompleted ( object sender, RunWorkerCompletedEventArgs e )
        {
            try
            {
                if (e.Result != null)
                {
                    throw (Exception)e.Result;
                }

                lvFiles.BeginUpdate();
                foreach (DirectoryInfo dir in explorer.Folders)
                {
                    ListViewItem item = new ListViewItem();
                    item.Text = dir.Name;
                    item.ImageIndex = 63;
                    item.Tag = dir;
                    lvFiles.Items.Add( item );
                }
                
                foreach (FileInfo file in explorer.Files)
                {
                    ListViewItem item = new ListViewItem();
                    item.Text = file.Name;
                    item.Tag = file;
                    item.ImageIndex = global.GetIconIndex( file.Name );
                    lvFiles.Items.Add( item );
                }
                lvFiles.EndUpdate();
                ProgressBar.Value = 0;
            }
            catch (FileNotFoundException fnfe)
            {
                lvFiles.Items.Add( UselessResources.ExpFilesNotFound );
                global.WriteLogs( Logger.LogsCategory.Exception, fnfe );
            }
            catch (UnauthorizedAccessException uae)
            {
                dirTree.SelectedNode.Remove();
                global.WriteLogs( Logger.LogsCategory.Exception, uae );
            }

        }

        private void LoadFiles ( string path, bool isRootNode )
        {
            try
            {
                this.lvFiles.Items.Clear();
                string args = String.Format( "{0}~{1}", path, isRootNode );

                if (bgWorkerLoadData.IsBusy)
                {
                    bgWorkerLoadData.CancelAsync();
                }

                while (true)
                {
                    if (!bgWorkerLoadData.CancellationPending)
                    {
                        bgWorkerLoadData.RunWorkerAsync( args );
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                global.WriteLogs( Logger.LogsCategory.Exception, ex );
            }
        }

        private void tabNetworkStatus_Click ( object sender, EventArgs e )
        {
            this.ucNetworkStatus.StartScanOnTabClick();
        }

        private void tabPrefrences_Click ( object sender, EventArgs e )
        {
            ucPreferencesTab1.LoadTabDataInPreference( tabCtrl );
        }
    }
}
